import 'package:pacsun/utils/notifyMsg.dart';
import 'package:flutter/material.dart';
import 'package:photo_manager/photo_manager.dart';
import 'widgets/mediaGrid.dart';

////////////////////////////////////////////////////////////////////////////////
///
///
///
///
///
///
///
///
///
///
///                        Donot touch me
///
///
///
///
///
///
///
///
///
///
////////////////////////////////////////////////////////////////////////////////

class SinglePhotoPicker extends StatefulWidget {
  final List<AssetEntity> initialSelectedPhotos;
  final int networkImageCount;

  const SinglePhotoPicker({
    Key? key,
    this.initialSelectedPhotos = const [],
    this.networkImageCount = 0,
  }) : super(key: key);

  @override
  State<SinglePhotoPicker> createState() => _SinglePhotoPickerState();
}

class _SinglePhotoPickerState extends State<SinglePhotoPicker> {
  List<AssetEntity> photoList = [];
  List<int> selectedPhotoIndexes = [];
  int maxPhotoSelect = 1;
  bool isLoading = true;
  AssetPathEntity? album;
  int _nextPhotoOrder = 1;
  late ValueNotifier<SelectionState> photoSelectionNotifier;

  @override
  void initState() {
    super.initState();
    _nextPhotoOrder = 1 + widget.networkImageCount;
    _fetchAllAssets();
    photoSelectionNotifier = ValueNotifier<SelectionState>(
        SelectionState(selectedIndexes: [], orderMap: {}));
  }

  @override
  void dispose() {
    photoSelectionNotifier.dispose();
    super.dispose();
  }

  Future<void> _fetchAllAssets() async {
    final PermissionState ps = await PhotoManager.requestPermissionExtend();
    if (!ps.isAuth) {
      setState(() => isLoading = false);
      return;
    }

    List<AssetPathEntity> albums = await PhotoManager.getAssetPathList(
      type: RequestType.image,
      onlyAll: true,
    );

    if (albums.isNotEmpty) {
      album = albums[0];
      final totalCount = await album!.assetCountAsync;

      final List<AssetEntity> allAssets =
          await album!.getAssetListRange(start: 0, end: totalCount);

      setState(() {
        photoList = allAssets.where((e) => e.type == AssetType.image).toList();
        isLoading = false;
        _restorePreviousSelections();
      });
    } else {
      setState(() => isLoading = false);
    }
  }

  void _restorePreviousSelections() {
    if (widget.initialSelectedPhotos.isNotEmpty) {
      final selectedIndexes = <int>[];
      final orderMap = <int, int>{};
      int order = 1 + widget.networkImageCount;

      for (final photo in widget.initialSelectedPhotos) {
        final index = photoList.indexWhere((p) => p.id == photo.id);
        if (index != -1) {
          selectedIndexes.add(index);
          orderMap[index] = order++;
        }
      }

      _nextPhotoOrder = order;
      photoSelectionNotifier.value = SelectionState(
        selectedIndexes: selectedIndexes,
        orderMap: orderMap,
      );
      selectedPhotoIndexes = selectedIndexes;
    }
  }

  void _selectPhoto(int index) {
    final currentState = photoSelectionNotifier.value;
    final currentList = List<int>.from(currentState.selectedIndexes);
    final currentOrder = Map<int, int>.from(currentState.orderMap);

    if (currentList.contains(index)) {
      currentList.remove(index);
      final removedOrder = currentOrder[index]!;
      currentOrder.remove(index);

      final updatedOrder = <int, int>{};
      for (final entry in currentOrder.entries) {
        if (entry.value > removedOrder) {
          updatedOrder[entry.key] = entry.value - 1;
        } else {
          updatedOrder[entry.key] = entry.value;
        }
      }
      currentOrder.clear();
      currentOrder.addAll(updatedOrder);
      _nextPhotoOrder--;
    } else if (widget.networkImageCount + currentList.length < maxPhotoSelect) {
      currentList.add(index);
      currentOrder[index] = _nextPhotoOrder;
      _nextPhotoOrder++;
    }

    photoSelectionNotifier.value = SelectionState(
      selectedIndexes: currentList,
      orderMap: currentOrder,
    );
    selectedPhotoIndexes = currentList;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      appBar: AppBar(
        backgroundColor: Colors.black,
        elevation: 0,
        leading: BackButton(color: Colors.white),
        title: Text('Select Photo', style: TextStyle(color: Colors.white)),
        centerTitle: true,
      ),
      body: isLoading
          ? Center(child: CircularProgressIndicator())
          : Stack(
              children: [
                ValueListenableBuilder<SelectionState>(
                  valueListenable: photoSelectionNotifier,
                  builder: (context, selectionState, child) {
                    return RepaintBoundary(
                      child: OptimizedMediaGrid(
                        key: ValueKey('photos_grid_${photoList.length}'),
                        mediaList: photoList,
                        selectedIndexes: selectionState.selectedIndexes,
                        orderMap: selectionState.orderMap,
                        maxSelect: maxPhotoSelect,
                        isVideo: false,
                        onTap: _selectPhoto,
                        networkImageCount: widget.networkImageCount,
                      ),
                    );
                  },
                ),
                ValueListenableBuilder<SelectionState>(
                  valueListenable: photoSelectionNotifier,
                  builder: (context, selectionState, child) {
                    if (selectionState.selectedIndexes.isEmpty) {
                      return const SizedBox.shrink();
                    }

                    final totalPhotoCount = widget.networkImageCount +
                        selectionState.selectedIndexes.length;

                    return Positioned(
                      bottom: 16,
                      right: 16,
                      child: SafeArea(
                        child: ElevatedButton(
                          style: ElevatedButton.styleFrom(
                              backgroundColor: Colors.red,
                              foregroundColor: Colors.white,
                              shape: StadiumBorder(),
                              padding: EdgeInsets.symmetric(
                                  horizontal: 24, vertical: 12)),
                          onPressed: () {
                            // Return the selected photos and pop
                            List<AssetEntity> selectedPhotos = selectionState
                                .selectedIndexes
                                .map((index) => photoList[index])
                                .toList();

                            Navigator.of(context).pop(selectedPhotos);
                          },
                          child: Text(
                            'SUBMIT ($totalPhotoCount/$maxPhotoSelect)',
                            style: TextStyle(fontWeight: FontWeight.bold),
                          ),
                        ),
                      ),
                    );
                  },
                ),
              ],
            ),
    );
  }
}

class SelectionState {
  final List<int> selectedIndexes;
  final Map<int, int> orderMap;

  SelectionState({
    required this.selectedIndexes,
    required this.orderMap,
  });

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is SelectionState &&
        _listEquals(selectedIndexes, other.selectedIndexes) &&
        _mapEquals(orderMap, other.orderMap);
  }

  @override
  int get hashCode => selectedIndexes.hashCode ^ orderMap.hashCode;

  bool _listEquals<T>(List<T>? a, List<T>? b) {
    if (a == null) return b == null;
    if (b == null || a.length != b.length) return false;
    for (int index = 0; index < a.length; index += 1) {
      if (a[index] != b[index]) return false;
    }
    return true;
  }

  bool _mapEquals<T, U>(Map<T, U>? a, Map<T, U>? b) {
    if (a == null) return b == null;
    if (b == null || a.length != b.length) return false;
    for (final T key in a.keys) {
      if (!b.containsKey(key) || b[key] != a[key]) return false;
    }
    return true;
  }
}

// Helper function to open the picker and get the result
Future<List<AssetEntity>?> openImagePicker(
  BuildContext context, {
  List<AssetEntity> initialSelectedPhotos = const [],
  int networkImageCount = 0,
}) async {
  final result = await Navigator.of(context).push<List<AssetEntity>>(
    MaterialPageRoute(
      builder: (context) => SinglePhotoPicker(
        initialSelectedPhotos: initialSelectedPhotos,
        networkImageCount: networkImageCount,
      ),
    ),
  );

  return result;
}
